package com.wdl.modules.myhouse.security.filter;


import com.auth0.jwt.exceptions.TokenExpiredException;
import com.wdl.modules.myhouse.exception.TokenException;
import com.wdl.modules.myhouse.security.entity.UserInfo;
import com.wdl.modules.myhouse.security.common.SecurityConstant;
import com.wdl.modules.myhouse.utils.util.JWTUtils;
import com.wdl.modules.myhouse.utils.util.JsonUtil;
import com.wdl.modules.myhouse.utils.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 昏昏的君
 */
@Component
@Slf4j
public class TokenFilter extends OncePerRequestFilter {


    @Autowired
    private RedisUtil redisUtil;

    private String[] excludPath = {
            "^/security/\\w*"
    };


    @Override
    protected void initFilterBean() throws ServletException {
        // todo 文件读取配置类


    }

    @Override
    protected void doFilterInternal(HttpServletRequest req, HttpServletResponse resp, FilterChain filterChain) throws ServletException, IOException {
        //跳过一些路径的token检验
        String sPath = req.getServletPath();
        Boolean flag = false;
        for (String path : excludPath) {
            if (sPath.matches(path)) {
                flag = true;
                break;
            }
        }
        if (!flag) {
            String token = req.getHeader(SecurityConstant.TOKEN_COOKIE_NAME);
            if (token != null && !token.isEmpty() && !"null".equals(token) && !"undefine".equals(token)) {
                log.warn("token为空");
                String user = null;
                try {
                    Integer uid = JWTUtils.getToken(token).getClaim(SecurityConstant.TOKEN_FIELD).asInt();
                    user = redisUtil.getValue(uid.toString());
                } catch (Exception e) {
                    req.setAttribute("LOGINException", new TokenException(e.getMessage()));
                    log.warn("TOKEN-FILTER:  JWT解析异常token 不合法，token:" + token);
                }
                if (user != null && !user.isEmpty()) {
                    UserInfo userInfo = JsonUtil.string2Obj(user, UserInfo.class);
                    UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userInfo, userInfo.getPassword(), userInfo.getAuthorities());
                    authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(req));
                    SecurityContextHolder.getContext().setAuthentication(authenticationToken);
                }else{
                    log.warn("token解析用户出现异常");
                }
            }
        }
        log.info("Token过滤器放行");
        filterChain.doFilter(req, resp);
    }
}
